package com.bringspring.visualdev.base.controller;


import com.bringspring.common.base.ActionResult;
import com.bringspring.common.base.vo.ListVO;
import com.bringspring.common.base.vo.PageListVO;
import com.bringspring.common.base.vo.PaginationVO;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.exception.DataException;
import com.bringspring.common.model.visiual.*;
import com.bringspring.common.model.visiual.fields.FieLdsModel;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.RandomUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.enums.DictionaryDataEnum;
import com.bringspring.system.base.exception.WorkFlowException;
import com.bringspring.system.base.util.JsonUtilEx;
import com.bringspring.system.base.entity.DictionaryDataEntity;
import com.bringspring.system.base.entity.ModuleEntity;
import com.bringspring.system.base.model.online.VisualMenuModel;
import com.bringspring.system.base.service.DictionaryDataService;
import com.bringspring.system.base.service.ModuleService;
import com.bringspring.system.base.util.visualUtil.PubulishUtil;
import com.bringspring.system.permission.entity.UserEntity;
import com.bringspring.system.permission.service.UserService;
import com.bringspring.visualdev.base.entity.VisualdevEntity;
import com.bringspring.visualdev.base.model.*;
import com.bringspring.visualdev.base.model.template6.BtnData;
import com.bringspring.visualdev.base.service.VisualdevService;
import com.bringspring.visualdev.base.util.VisualUtil;
import com.bringspring.visualdev.onlinedev.model.PaginationModel;
import com.bringspring.visualdev.onlinedev.service.VisualdevModelDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 可视化基础模块
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月27日 上午9:18
 */
@Api(tags = "可视化基础模块" , value = "Base")
@RestController
@RequestMapping("/api/visualdev/Base")
public class VisualdevController {

    @Autowired
    private VisualdevService visualdevService;
    @Autowired
    private UserService userService;
    @Autowired
    private DictionaryDataService dictionaryDataService;
    @Autowired
    private VisualdevModelDataService visualdevModelDataService;
    @Autowired
    private PubulishUtil pubulishUtil;
    @Autowired
    private ModuleService moduleService;


    @ApiOperation("获取功能列表")
    @GetMapping
    public ActionResult<PageListVO<VisualFunctionModel>> list(PaginationVisualdev paginationVisualdev) {
        // 全部功能表单模板
        List<VisualdevEntity> data = visualdevService.getList(paginationVisualdev);
        List<String> userId = data.stream().map(t -> t.getCreatorUserId()).collect(Collectors.toList());
        List<String> lastUserId = data.stream().map(t -> t.getLastModifyUserId()).collect(Collectors.toList());
        List<UserEntity> userEntities = userService.getUserName(userId);
        List<UserEntity> lastUserIdEntities = userService.getUserName(lastUserId);
        // 表单类型
        List<DictionaryDataEntity> dictionList = dictionaryDataService.getList(DictionaryDataEnum.getTypeId(paginationVisualdev.getType()));
        List<VisualFunctionModel> modelAll = new LinkedList<>();

        // 遍历功能表单模板
        for (VisualdevEntity entity : data) {
            VisualFunctionModel model = JsonUtil.getJsonToBean(entity, VisualFunctionModel.class);
            // 是否在表单类型中存在，若存在进行装配
            DictionaryDataEntity dataEntity = dictionList.stream().filter(t -> t.getId().equals(entity.getCategory())).findFirst().orElse(null);
            //避免导入的功能丢失
            model.setCategory(dataEntity != null ? dataEntity.getFullName() : null);
            UserEntity creatorUser = userEntities.stream().filter(t -> t.getId().equals(model.getCreatorUserId())).findFirst().orElse(null);
            model.setCreatorUserId(creatorUser != null ? creatorUser.getRealName() + "/" + creatorUser.getAccount() : "");
            UserEntity lastmodifyuser = lastUserIdEntities.stream().filter(t -> t.getId().equals(model.getLastModifyUserId())).findFirst().orElse(null);
            model.setLastModifyUserId(lastmodifyuser != null ? lastmodifyuser.getRealName() + "/" + lastmodifyuser.getAccount() : "");
            List<ModuleEntity> moduleList = moduleService.getModuleList(entity.getId());
            model.setAppIsRelease(0);
            model.setPcIsRelease(0);
            if (moduleList.size()>0){
                ModuleEntity appModuleEntity = moduleList.stream().filter(module -> "app".equalsIgnoreCase(module.getCategory())).findFirst().orElse(null);
                ModuleEntity pcModuleEntity = moduleList.stream().filter(module -> "web".equalsIgnoreCase(module.getCategory())).findFirst().orElse(null);
                model.setAppIsRelease(Objects.nonNull(appModuleEntity) ?  1 : 0);
                model.setPcIsRelease(Objects.nonNull(pcModuleEntity) ?  1 : 0);
            }
            modelAll.add(model);
        }
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationVisualdev, PaginationVO.class);
        return ActionResult.page(modelAll, paginationVO);
    }

    @ApiOperation("获取功能列表下拉框")
    @GetMapping("/Selector")
    public ActionResult selectorList(Integer type) {
        List<VisualdevEntity> list = visualdevService.getList().stream().filter(t -> t.getState() == 1 ).collect(Collectors.toList());
        List<DictionaryDataEntity> dataEntityList = new ArrayList<>(16);
        List<VisualdevTreeVO> voList = new ArrayList<>();
        HashSet<String> cate = new HashSet<>(16);
        if (type != null) {
            list = list.stream().filter(t -> type.equals(t.getType())).collect(Collectors.toList());
            dataEntityList = dictionaryDataService.getList(DictionaryDataEnum.getTypeId(type));
            // 遍历数据字典得到外部分类
            for (DictionaryDataEntity dataEntity : dataEntityList) {
                List<VisualdevEntity> num = list.stream().filter(t -> dataEntity.getId().equals(t.getCategory())).collect(Collectors.toList());
                if (num.size() <= 0) {
                    continue;
                }
                int i = cate.size();
                cate.add(dataEntity.getId());
                if (cate.size() == i + 1) {
                    VisualdevTreeVO visualdevTreeVO = new VisualdevTreeVO();
                    visualdevTreeVO.setId(dataEntity.getId());
                    visualdevTreeVO.setFullName(dataEntity.getFullName());
                    visualdevTreeVO.setHasChildren(true);
                    voList.add(visualdevTreeVO);
                }
            }
        } else {
            // type为空时
            for (VisualdevEntity entity : list) {
                if (!StringUtils.isEmpty(entity.getCategory())) {
                    DictionaryDataEntity dataEntity = dictionaryDataService.getInfo(entity.getCategory());
                    if (dataEntity != null) {
                        int i = cate.size();
                        cate.add(dataEntity.getId());
                        if (cate.size() == i + 1) {
                            VisualdevTreeVO visualdevTreeVO = new VisualdevTreeVO();
                            visualdevTreeVO.setId(entity.getCategory());
                            visualdevTreeVO.setFullName(dataEntity.getFullName());
                            visualdevTreeVO.setHasChildren(true);
                            voList.add(visualdevTreeVO);
                        }
                    }
                }
            }
        }
        for (VisualdevTreeVO vo : voList) {
            List<VisualdevTreeChildModel> visualdevTreeChildModelList = new ArrayList<>();
            for (VisualdevEntity entity : list) {
                if (vo.getId().equals(entity.getCategory())) {
                    VisualdevTreeChildModel model = JsonUtil.getJsonToBean(entity, VisualdevTreeChildModel.class);
                    visualdevTreeChildModelList.add(model);
                }
            }
            vo.setChildren(visualdevTreeChildModelList);
        }
        ListVO listVO = new ListVO();
        listVO.setList(voList);
        return ActionResult.success(listVO);
    }

    @ApiOperation("获取功能信息")
    @GetMapping("/{id}")
    public ActionResult info(@PathVariable("id") String id) throws DataException {
        VisualdevEntity entity = visualdevService.getInfo(id);
        VisualDevInfoVO vo = JsonUtilEx.getJsonToBeanEx(entity, VisualDevInfoVO.class);
        return ActionResult.success(vo);
    }

    /**
     * 获取表单主表属性下拉框
     * @param id
     * @return
     */
    @ApiOperation("获取表单主表属性下拉框")
    @GetMapping("/{id}/FormDataFields")
    public ActionResult getFormData(@PathVariable("id") String id) {
        List<FormDataField> fieldList = visualdevModelDataService.fieldList(id);
        ListVO<FormDataField> listVO = new ListVO();
        listVO.setList(fieldList);
        return ActionResult.success(listVO);
    }

    /**
     * 关联数据分页数据
     * @param id
     * @param paginationModel
     * @return
     */
    @ApiOperation("关联数据分页数据")
    @GetMapping("/{id}/FieldDataSelect")
    public ActionResult getFormData(@PathVariable("id") String id, PaginationModel paginationModel) {
        VisualdevEntity entity = visualdevService.getInfo(id);
        List<Map<String, Object>> realList = visualdevModelDataService.getPageList(entity, paginationModel);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationModel, PaginationVO.class);
        return ActionResult.page(realList, paginationVO);
    }


    /**
     * 复制功能
     *
     * @param id
     * @return
     */
    @ApiOperation("复制功能")
    @PostMapping("/{id}/Actions/Copy")
    public ActionResult copyInfo(@PathVariable("id") String id) throws WorkFlowException {
        VisualdevEntity entity = visualdevService.getInfo(id);
        entity.setState(0);
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        entity.setFullName(entity.getFullName() + ".副本" + copyNum);
        entity.setLastModifyTime(null);
        entity.setLastModifyUserId(null);
        entity.setCreatorTime(null);
        entity.setId(RandomUtil.uuId());
        entity.setEnCode(entity.getEnCode() + copyNum);
        VisualdevEntity entity1 = JsonUtil.getJsonToBean(entity, VisualdevEntity.class);
        if (entity1.getEnCode().length()>50 || entity1.getFullName().length()>50){
            return ActionResult.fail("已到达该模板复制上限，请复制源模板");
        }
        visualdevService.create(entity1);
        return ActionResult.success("复制功能成功");
    }


    /**
     * 更新功能状态
     *
     * @param id 主键值
     * @return
     */
    @ApiOperation("更新功能状态")
    @PutMapping("/{id}/Actions/State")
    public ActionResult update(@PathVariable("id") String id) throws WorkFlowException {
        VisualdevEntity entity = visualdevService.getInfo(id);
        if (entity != null) {
            if (entity.getState() == 1) {
                entity.setState(0);
            } else {
                entity.setState(1);
            }
            boolean flag = visualdevService.update(entity.getId(), entity);
            if (flag == false) {
                return ActionResult.fail("更新失败，任务不存在");
            }
        }
        return ActionResult.success(MsgCode.SU004.get());
    }


    @ApiOperation("新建功能")
    @PostMapping
    public ActionResult create(@RequestBody VisualDevCrForm visualDevCrForm) throws WorkFlowException {
        VisualdevEntity entity = JsonUtil.getJsonToBean(JsonUtilEx.getObjectToString(visualDevCrForm), VisualdevEntity.class);
        //判断子表是否复用
        RecursionForm recursionForm = new RecursionForm();
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        recursionForm.setList(list);
        List<TableModel> tableModelList = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);
        recursionForm.setTableModelList(tableModelList);
        if (FormCloumnUtil.repetition(recursionForm, new ArrayList<>())) {
            return ActionResult.fail("子表重复");
        }
        //判断编码是否重复
        if (visualdevService.getObjByEncode(entity.getEnCode(),entity.getType())>0) {
            return ActionResult.fail("编码重复");
        }
        //判断编码是否重复
        if (visualdevService.getCountByName(entity.getFullName(),entity.getType())>0) {
            return ActionResult.fail("名称重复");
        }
        visualdevService.create(entity);
        return ActionResult.success(MsgCode.SU001.get());
    }


    @ApiOperation("修改功能")
    @PutMapping("/{id}")
    public ActionResult update(@PathVariable("id") String id, @RequestBody VisualDevUpForm visualDevUpForm) throws WorkFlowException {
        VisualdevEntity visualdevEntity = visualdevService.getInfo(id);
        String enCode = visualdevEntity.getEnCode();
        String fullName = visualdevEntity.getFullName();
        VisualdevEntity entity = JsonUtil.getJsonToBean(JsonUtilEx.getObjectToString(visualDevUpForm), VisualdevEntity.class);
        List<TableModel> tableModelList = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);

        if (tableModelList.size()==0){
            return ActionResult.fail("必须存在至少一个表");
        }

        //判断编码是否重复
        if (!enCode.equals(visualDevUpForm.getEnCode())){
            if (visualdevService.getObjByEncode(entity.getEnCode(),entity.getType())>0) {
                return ActionResult.fail("编码重复");
            }
        }

        //判断编码是否重复
        if (!fullName.equals(visualDevUpForm.getFullName())){
            if (visualdevService.getCountByName(entity.getFullName(), entity.getType())>0) {
                return ActionResult.fail("名称重复");
            }
        }

        //判断子表是否复用
        RecursionForm recursionForm = new RecursionForm();
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        recursionForm.setList(list);

        recursionForm.setTableModelList(tableModelList);
        if (FormCloumnUtil.repetition(recursionForm, new ArrayList<>())) {
            return ActionResult.fail("子表重复");
        }

        boolean flag = visualdevService.update(id, entity);
        if (flag == false) {
            return ActionResult.fail(MsgCode.FA002.get());
        }
        return ActionResult.success(MsgCode.SU004.get());
    }


    @ApiOperation("删除功能")
    @DeleteMapping("/{id}")
    public ActionResult delete(@PathVariable("id") String id) throws WorkFlowException {
        VisualdevEntity entity = visualdevService.getInfo(id);
        if (entity != null) {
            visualdevService.delete(entity);
            return ActionResult.success(MsgCode.SU003.get());
        }
        return ActionResult.fail(MsgCode.FA003.get());
    }

    @ApiOperation("获取模板按钮和列表字段")
    @GetMapping("/ModuleBtn")
    public ActionResult getModuleBtn(String moduleId) {
        VisualdevEntity visualdevEntity = visualdevService.getInfo(moduleId);
        //去除模板中的F_
        VisualUtil.delfKey(visualdevEntity);
        List<BtnData> btnData = new ArrayList<>();
        Map<String, Object> column = JsonUtil.stringToMap(visualdevEntity.getColumnData());
        if (column.get("columnBtnsList") != null) {
            btnData.addAll(JsonUtil.getJsonToList(JsonUtil.getJsonToListMap(column.get("columnBtnsList").toString()), BtnData.class));
        }
        if (column.get("btnsList") != null) {
            btnData.addAll(JsonUtil.getJsonToList(JsonUtil.getJsonToListMap(column.get("btnsList").toString()), BtnData.class));
        }
        return ActionResult.success(btnData);
    }

    @ApiOperation("发布功能")
    @PostMapping("/{id}/Actions/Release")
    public ActionResult publish(@PathVariable("id") String id,@RequestBody VisualDevPubModel visualDevPubModel)  {
        VisualdevEntity visualdevEntity = visualdevService.getInfo(id);
        if(visualdevEntity.getState()==0){
            return ActionResult.fail("该功能已停用无法同步菜单!");
        }
        //发布
        VisualMenuModel visual = VisualUtil.getVisual(visualdevEntity,visualDevPubModel);
        visual.setApp(visualDevPubModel.getApp());
        visual.setPc(visualDevPubModel.getPc());
        visual.setAppModuleParentId(visualDevPubModel.getAppModuleParentId());
        visual.setPcModuleParentId(visualDevPubModel.getPcModuleParentId());
        Integer integer = pubulishUtil.publishMenu(visual);
        if (integer==2){
            return ActionResult.fail("同步失败,检查编码或名称是否重复");
        }
        if (integer==3){
            return ActionResult.fail("请选择父级菜单");
        }
        return ActionResult.success("同步成功");
    }
}
